home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 15 / CU Amiga Magazine's Super CD-ROM 15 (1997)(EMAP Images)(GB)[!][issue 1997-10].iso / CUCD / Graphics / Ghostscript / source / libpng / pngrutil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-15  |  59.4 KB  |  2,138 lines

  1.  
  2. /* pngrutil.c - utilities to read a PNG file
  3.  
  4.    libpng 1.0 beta 6 - version 0.96
  5.    For conditions of distribution and use, see copyright notice in png.h
  6.    Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
  7.    Copyright (c) 1996, 1997 Andreas Dilger
  8.    May 12, 1997
  9.    */
  10.  
  11. #define PNG_INTERNAL
  12. #include "png.h"
  13.  
  14. #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
  15. /* Grab an unsigned 32-bit integer from a buffer in big endian format. */
  16. png_uint_32
  17. png_get_uint_32(png_bytep buf)
  18. {
  19.    png_uint_32 i;
  20.  
  21.    i = ((png_uint_32)(*buf) << 24) +
  22.       ((png_uint_32)(*(buf + 1)) << 16) +
  23.       ((png_uint_32)(*(buf + 2)) << 8) +
  24.       (png_uint_32)(*(buf + 3));
  25.  
  26.    return i;
  27. }
  28.  
  29. #if defined(PNG_READ_pCAL_SUPPORTED)
  30. /* Grab a signed 32-bit integer from a buffer in big endian format.  The
  31.  * data is stored in the PNG file in two's complement format, and it is
  32.  * assumed that the machine format for signed integers is the same. */
  33. png_int_32
  34. png_get_int_32(png_bytep buf)
  35. {
  36.    png_int_32 i;
  37.  
  38.    i = ((png_int_32)(*buf) << 24) +
  39.       ((png_int_32)(*(buf + 1)) << 16) +
  40.       ((png_int_32)(*(buf + 2)) << 8) +
  41.       (png_int_32)(*(buf + 3));
  42.  
  43.    return i;
  44. }
  45. #endif /* PNG_READ_pCAL_SUPPORTED */
  46.  
  47. /* Grab an unsigned 16-bit integer from a buffer in big endian format. */
  48. png_uint_16
  49. png_get_uint_16(png_bytep buf)
  50. {
  51.    png_uint_16 i;
  52.  
  53.    i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
  54.       (png_uint_16)(*(buf + 1)));
  55.  
  56.    return i;
  57. }
  58. #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
  59.  
  60. /* Set the action on getting a CRC error for an ancillary or critical chunk. */
  61. void
  62. png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
  63. {
  64.    png_debug(1, "in png_set_crc_action\n");
  65.    /* Tell libpng how we react to CRC errors in critical chunks */
  66.    switch (crit_action)
  67.    {
  68.       case PNG_CRC_NO_CHANGE:                        /* leave setting as is */
  69.          break;
  70.       case PNG_CRC_WARN_USE:                               /* warn/use data */
  71.          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  72.          png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
  73.          break;
  74.       case PNG_CRC_QUIET_USE:                             /* quiet/use data */
  75.          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  76.          png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
  77.                            PNG_FLAG_CRC_CRITICAL_IGNORE;
  78.          break;
  79.       case PNG_CRC_WARN_DISCARD:    /* not a valid action for critical data */
  80.          png_warning(png_ptr, "Can't discard critical data on CRC error.");
  81.       case PNG_CRC_ERROR_QUIT:                                /* error/quit */
  82.       case PNG_CRC_DEFAULT:
  83.       default:
  84.          png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
  85.          break;
  86.    }
  87.  
  88.    switch (ancil_action)
  89.    {
  90.       case PNG_CRC_NO_CHANGE:                       /* leave setting as is */
  91.          break;
  92.       case PNG_CRC_WARN_USE:                              /* warn/use data */
  93.          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  94.          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
  95.          break;
  96.       case PNG_CRC_QUIET_USE:                            /* quiet/use data */
  97.          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  98.          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
  99.                            PNG_FLAG_CRC_ANCILLARY_NOWARN;
  100.          break;
  101.       case PNG_CRC_ERROR_QUIT:                               /* error/quit */
  102.          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  103.          png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
  104.          break;
  105.       case PNG_CRC_WARN_DISCARD:                      /* warn/discard data */
  106.       case PNG_CRC_DEFAULT:
  107.       default:
  108.          png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
  109.          break;
  110.    }
  111. }
  112.  
  113. /* Read data, and (optionally) run it through the CRC. */
  114. void
  115. png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
  116. {
  117.    png_read_data(png_ptr, buf, length);
  118.    png_calculate_crc(png_ptr, buf, length);
  119. }
  120.  
  121. /* Optionally skip data and then check the CRC.  Depending on whether we
  122.    are reading a ancillary or critical chunk, and how the program has set
  123.    things up, we may calculate the CRC on the data and print a message.
  124.    Returns '1' if there was a CRC error, '0' otherwise. */
  125. int
  126. png_crc_finish(png_structp png_ptr, png_uint_32 skip)
  127. {
  128.    png_uint_32 i;
  129.  
  130.    for (i = skip; i > (png_uint_32)png_ptr->zbuf_size; i -= png_ptr->zbuf_size)
  131.    {
  132.       png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
  133.    }
  134.    if (i)
  135.    {
  136.       png_crc_read(png_ptr, png_ptr->zbuf, (png_size_t)i);
  137.    }
  138.  
  139.    if (png_crc_error(png_ptr))
  140.    {
  141.       char msg[80];
  142.  
  143.       sprintf(msg,"CRC error in %s", png_ptr->chunk_name);
  144.  
  145.       if ((png_ptr->chunk_name[0] & 0x20 &&                /* Ancillary */
  146.            !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
  147.           (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
  148.            png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))
  149.       {
  150.          png_warning(png_ptr, msg);
  151.       }
  152.       else
  153.       {
  154.          png_error(png_ptr, msg);
  155.       }
  156.       return 1;
  157.    }
  158.  
  159.    return 0;
  160. }
  161.  
  162. /* Compare the CRC stored in the PNG file with that calulated by libpng from
  163.    the data it has read thus far. */
  164. int
  165. png_crc_error(png_structp png_ptr)
  166. {
  167.    png_byte crc_bytes[4];
  168.    png_uint_32 crc;
  169.    int need_crc = 1;
  170.  
  171.    if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
  172.    {
  173.       if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
  174.           (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
  175.          need_crc = 0;
  176.    }
  177.    else                                                    /* critical */
  178.    {
  179.       if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
  180.          need_crc = 0;
  181.    }
  182.  
  183.    png_read_data(png_ptr, crc_bytes, 4);
  184.  
  185.    if (need_crc)
  186.    {
  187.       crc = png_get_uint_32(crc_bytes);
  188. #ifdef PNG_USE_OWN_CRC
  189.       return (((crc^0xffffffffL)&0xffffffffL) != (png_ptr->crc&0xffffffffL));
  190. #else
  191.       return (crc != png_ptr->crc);
  192. #endif
  193.    }
  194.    else
  195.       return 0;
  196. }
  197.  
  198.  
  199. /* read and check the IDHR chunk */
  200. void
  201. png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  202. {
  203.    png_byte buf[13];
  204.    png_uint_32 width, height;
  205.    int bit_depth, color_type, compression_type, filter_type;
  206.    int interlace_type;
  207.  
  208.    png_debug(1, "in png_handle_IHDR\n");
  209.  
  210.    if (png_ptr->mode != PNG_BEFORE_IHDR)
  211.       png_error(png_ptr, "Out of place IHDR");
  212.  
  213.    /* check the length */
  214.    if (length != 13)
  215.       png_error(png_ptr, "Invalid IHDR chunk");
  216.  
  217.    png_ptr->mode |= PNG_HAVE_IHDR;
  218.  
  219.    png_crc_read(png_ptr, buf, 13);
  220.    png_crc_finish(png_ptr, 0);
  221.  
  222.    width = png_get_uint_32(buf);
  223.    height = png_get_uint_32(buf + 4);
  224.    bit_depth = buf[8];
  225.    color_type = buf[9];
  226.    compression_type = buf[10];
  227.    filter_type = buf[11];
  228.    interlace_type = buf[12];
  229.  
  230.    /* check for width and height valid values */
  231.    if (width == 0 || width > 2147483647 || height == 0 || height > 2147483647)
  232.       png_error(png_ptr, "Invalid image size in IHDR");
  233.  
  234.    /* check other values */
  235.    if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
  236.       bit_depth != 8 && bit_depth != 16)
  237.       png_error(png_ptr, "Invalid bit depth in IHDR");
  238.  
  239.    if (color_type < 0 || color_type == 1 ||
  240.       color_type == 5 || color_type > 6)
  241.       png_error(png_ptr, "Invalid color type in IHDR");
  242.  
  243.    if ((color_type == PNG_COLOR_TYPE_PALETTE && bit_depth) > 8 ||
  244.        ((color_type == PNG_COLOR_TYPE_RGB ||
  245.          color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
  246.          color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
  247.       png_error(png_ptr, "Invalid color type/bit depth combination in IHDR");
  248.  
  249.    if (interlace_type > PNG_INTERLACE_ADAM7)
  250.       png_error(png_ptr, "Unknown interlace method in IHDR");
  251.  
  252.    if (compression_type != PNG_COMPRESSION_TYPE_BASE)
  253.       png_error(png_ptr, "Unknown compression method in IHDR");
  254.  
  255.    if (filter_type != PNG_FILTER_TYPE_BASE)
  256.       png_error(png_ptr, "Unknown filter method in IHDR");
  257.  
  258.    /* set internal variables */
  259.    png_ptr->width = width;
  260.    png_ptr->height = height;
  261.    png_ptr->bit_depth = (png_byte)bit_depth;
  262.    png_ptr->interlaced = (png_byte)interlace_type;
  263.    png_ptr->color_type = (png_byte)color_type;
  264.  
  265.    /* find number of channels */
  266.    switch (png_ptr->color_type)
  267.    {
  268.       case PNG_COLOR_TYPE_GRAY:
  269.       case PNG_COLOR_TYPE_PALETTE:
  270.          png_ptr->channels = 1;
  271.          break;
  272.       case PNG_COLOR_TYPE_RGB:
  273.          png_ptr->channels = 3;
  274.          break;
  275.       case PNG_COLOR_TYPE_GRAY_ALPHA:
  276.          png_ptr->channels = 2;
  277.          break;
  278.       case PNG_COLOR_TYPE_RGB_ALPHA:
  279.          png_ptr->channels = 4;
  280.          break;
  281.    }
  282.  
  283.    /* set up other useful info */
  284.    png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
  285.       png_ptr->channels);
  286.    png_ptr->rowbytes = ((png_ptr->width *
  287.       (png_uint_32)png_ptr->pixel_depth + 7) >> 3);
  288.    png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
  289.    png_debug1(3,"channels = %d\n", png_ptr->channels);
  290.    png_debug1(3,"rowbytes = %d\n", png_ptr->rowbytes);
  291.    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
  292.       color_type, interlace_type, compression_type, filter_type);
  293. }
  294.  
  295. /* read and check the palette */
  296. void
  297. png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  298. {
  299.    png_colorp palette;
  300.    int num, i;
  301.  
  302.    png_debug(1, "in png_handle_PLTE\n");
  303.  
  304.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  305.       png_error(png_ptr, "Missing IHDR before PLTE");
  306.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  307.    {
  308.       png_warning(png_ptr, "Invalid PLTE after IDAT");
  309.       png_crc_finish(png_ptr, length);
  310.       return;
  311.    }
  312.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  313.       png_error(png_ptr, "Duplicate PLTE chunk");
  314.  
  315.    png_ptr->mode |= PNG_HAVE_PLTE;
  316.  
  317. #if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
  318.    if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
  319.    {
  320.       png_crc_finish(png_ptr, length);
  321.       return;
  322.    }
  323. #endif
  324.  
  325.    if (length % 3)
  326.    {
  327.       if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
  328.       {
  329.          png_warning(png_ptr, "Invalid palette chunk");
  330.          png_crc_finish(png_ptr, length);
  331.          return;
  332.       }
  333.       else
  334.       {
  335.          png_error(png_ptr, "Invalid palette chunk");
  336.       }
  337.    }
  338.  
  339.    num = (int)length / 3;
  340.    palette = (png_colorp)png_malloc(png_ptr, num * sizeof (png_color));
  341.    png_ptr->flags |= PNG_FLAG_FREE_PALETTE;
  342.    for (i = 0; i < num; i++)
  343.    {
  344.       png_byte buf[3];
  345.  
  346.       png_crc_read(png_ptr, buf, 3);
  347.       /* don't depend upon png_color being any order */
  348.       palette[i].red = buf[0];
  349.       palette[i].green = buf[1];
  350.       palette[i].blue = buf[2];
  351.    }
  352.  
  353.    /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
  354.       whatever the normal CRC configuration tells us.  However, if we
  355.       have an RGB image, the PLTE can be considered ancillary, so
  356.       we will act as though it is. */
  357.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  358.    {
  359.       png_crc_finish(png_ptr, 0);
  360.    }
  361.    else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
  362.    {
  363.       char msg[80];
  364.  
  365.       sprintf(msg,"CRC error in %s", png_ptr->chunk_name);
  366.  
  367.       /* If we don't want to use the data from an ancillary chunk,
  368.          we have two options: an error abort, or a warning and we
  369.          ignore the data in this chunk (which should be OK, since
  370.          it's considered ancillary for a RGB or RGBA image). */
  371.       if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
  372.       {
  373.          if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
  374.          {
  375.             png_error(png_ptr, msg);
  376.          }
  377.          else
  378.          {
  379.             png_warning(png_ptr, msg);
  380.             png_ptr->flags &= ~PNG_FLAG_FREE_PALETTE;
  381.             png_free(png_ptr, palette);
  382.             return;
  383.          }
  384.       }
  385.       /* Otherwise, we (optionally) emit a warning and use the chunk. */
  386.       else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
  387.       {
  388.          png_warning(png_ptr, msg);
  389.       }
  390.    }
  391.  
  392.    png_ptr->palette = palette;
  393.    png_ptr->num_palette = (png_uint_16)num;
  394.    png_set_PLTE(png_ptr, info_ptr, palette, num);
  395. }
  396.  
  397. void
  398. png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  399. {
  400.    png_debug(1, "in png_handle_IEND\n");
  401.  
  402.    if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
  403.    {
  404.       png_error(png_ptr, "No image in file");
  405.    }
  406.  
  407.    png_ptr->mode |= PNG_AFTER_IDAT | PNG_HAVE_IEND;
  408.  
  409.    if (length != 0)
  410.    {
  411.       png_warning(png_ptr, "Incorrect IEND chunk length");
  412.    }
  413.    png_crc_finish(png_ptr, length);
  414. }
  415.  
  416. #if defined(PNG_READ_gAMA_SUPPORTED)
  417. void
  418. png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  419. {
  420.    png_uint_32 igamma;
  421.    float file_gamma;
  422.    png_byte buf[4];
  423.  
  424.    png_debug(1, "in png_handle_gAMA\n");
  425.  
  426.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  427.       png_error(png_ptr, "Missing IHDR before gAMA");
  428.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  429.    {
  430.       png_warning(png_ptr, "Invalid gAMA after IDAT");
  431.       png_crc_finish(png_ptr, length);
  432.       return;
  433.    }
  434.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  435.       /* Should be an error, but we can cope with it */
  436.       png_warning(png_ptr, "Out of place gAMA chunk");
  437.    else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_gAMA)
  438.    {
  439.       png_warning(png_ptr, "Duplicate gAMA chunk");
  440.       png_crc_finish(png_ptr, length);
  441.       return;
  442.    }
  443.  
  444.    if (length != 4)
  445.    {
  446.       png_warning(png_ptr, "Incorrect gAMA chunk length");
  447.       png_crc_finish(png_ptr, length);
  448.       return;
  449.    }
  450.  
  451.    png_crc_read(png_ptr, buf, 4);
  452.    if (png_crc_finish(png_ptr, 0))
  453.       return;
  454.  
  455.    igamma = png_get_uint_32(buf);
  456.    /* check for zero gamma */
  457.    if (igamma == 0)
  458.       return;
  459.  
  460.    file_gamma = (float)igamma / (float)100000.0;
  461.    png_ptr->gamma = file_gamma;
  462.    png_set_gAMA(png_ptr, info_ptr, file_gamma);
  463. }
  464. #endif
  465.  
  466. #if defined(PNG_READ_sBIT_SUPPORTED)
  467. void
  468. png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  469. {
  470.    png_size_t truelen;
  471.    png_byte buf[4];
  472.  
  473.    png_debug(1, "in png_handle_sBIT\n");
  474.  
  475.    buf[0] = buf[1] = buf[2] = buf[3] = 0;
  476.  
  477.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  478.       png_error(png_ptr, "Missing IHDR before sBIT");
  479.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  480.    {
  481.       png_warning(png_ptr, "Invalid sBIT after IDAT");
  482.       png_crc_finish(png_ptr, length);
  483.       return;
  484.    }
  485.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  486.       /* Should be an error, but we can cope with it */
  487.       png_warning(png_ptr, "Out of place sBIT chunk");
  488.    else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sBIT)
  489.    {
  490.       png_warning(png_ptr, "Duplicate sBIT chunk");
  491.       png_crc_finish(png_ptr, length);
  492.       return;
  493.    }
  494.  
  495.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  496.       truelen = 3;
  497.    else
  498.       truelen = (png_size_t)png_ptr->channels;
  499.  
  500.    if (length != truelen)
  501.    {
  502.       png_warning(png_ptr, "Incorrect sBIT chunk length");
  503.       png_crc_finish(png_ptr, length);
  504.       return;
  505.    }
  506.  
  507.    png_crc_read(png_ptr, buf, truelen);
  508.    if (png_crc_finish(png_ptr, 0))
  509.       return;
  510.  
  511.    if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  512.    {
  513.       png_ptr->sig_bit.red = buf[0];
  514.       png_ptr->sig_bit.green = buf[1];
  515.       png_ptr->sig_bit.blue = buf[2];
  516.       png_ptr->sig_bit.alpha = buf[3];
  517.    }
  518.    else
  519.    {
  520.       png_ptr->sig_bit.gray = buf[0];
  521.       png_ptr->sig_bit.alpha = buf[1];
  522.    }
  523.    png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
  524. }
  525. #endif
  526.  
  527. #if defined(PNG_READ_cHRM_SUPPORTED)
  528. void
  529. png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  530. {
  531.    png_byte buf[4];
  532.    png_uint_32 val;
  533.    float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
  534.  
  535.    png_debug(1, "in png_handle_cHRM\n");
  536.  
  537.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  538.       png_error(png_ptr, "Missing IHDR before sBIT");
  539.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  540.    {
  541.       png_warning(png_ptr, "Invalid cHRM after IDAT");
  542.       png_crc_finish(png_ptr, length);
  543.       return;
  544.    }
  545.    else if (png_ptr->mode & PNG_HAVE_PLTE)
  546.       /* Should be an error, but we can cope with it */
  547.       png_warning(png_ptr, "Missing PLTE before cHRM");
  548.    else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_cHRM)
  549.    {
  550.       png_warning(png_ptr, "Duplicate cHRM chunk");
  551.       png_crc_finish(png_ptr, length);
  552.       return;
  553.    }
  554.  
  555.    if (length != 32)
  556.    {
  557.       png_warning(png_ptr, "Incorrect cHRM chunk length");
  558.       png_crc_finish(png_ptr, length);
  559.       return;
  560.    }
  561.  
  562.    png_crc_read(png_ptr, buf, 4);
  563.    val = png_get_uint_32(buf);
  564.    white_x = (float)val / (float)100000.0;
  565.  
  566.    png_crc_read(png_ptr, buf, 4);
  567.    val = png_get_uint_32(buf);
  568.    white_y = (float)val / (float)100000.0;
  569.  
  570.    if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
  571.        white_x + white_y > 1.0)
  572.    {
  573.       png_warning(png_ptr, "Invalid cHRM white point");
  574.       png_crc_finish(png_ptr, 24);
  575.       return;
  576.    }
  577.  
  578.    png_crc_read(png_ptr, buf, 4);
  579.    val = png_get_uint_32(buf);
  580.    red_x = (float)val / (float)100000.0;
  581.  
  582.    png_crc_read(png_ptr, buf, 4);
  583.    val = png_get_uint_32(buf);
  584.    red_y = (float)val / (float)100000.0;
  585.  
  586.    if (red_x < 0 || red_x > 0.8 || red_y < 0 || red_y > 0.8 ||
  587.        red_x + red_y > 1.0)
  588.    {
  589.       png_warning(png_ptr, "Invalid cHRM red point");
  590.       png_crc_finish(png_ptr, 16);
  591.       return;
  592.    }
  593.  
  594.    png_crc_read(png_ptr, buf, 4);
  595.    val = png_get_uint_32(buf);
  596.    green_x = (float)val / (float)100000.0;
  597.  
  598.    png_crc_read(png_ptr, buf, 4);
  599.    val = png_get_uint_32(buf);
  600.    green_y = (float)val / (float)100000.0;
  601.  
  602.    if (green_x < 0 || green_x > 0.8 || green_y < 0 || green_y > 0.8 ||
  603.        green_x + green_y > 1.0)
  604.    {
  605.       png_warning(png_ptr, "Invalid cHRM green point");
  606.       png_crc_finish(png_ptr, 8);
  607.       return;
  608.    }
  609.  
  610.    png_crc_read(png_ptr, buf, 4);
  611.    val = png_get_uint_32(buf);
  612.    blue_x = (float)val / (float)100000.0;
  613.  
  614.    png_crc_read(png_ptr, buf, 4);
  615.    val = png_get_uint_32(buf);
  616.    blue_y = (float)val / (float)100000.0;
  617.  
  618.    if (blue_x < 0 || blue_x > 0.8 || blue_y < 0 || blue_y > 0.8 ||
  619.        blue_x + blue_y > 1.0)
  620.    {
  621.       png_warning(png_ptr, "Invalid cHRM blue point");
  622.       png_crc_finish(png_ptr, 0);
  623.       return;
  624.    }
  625.  
  626.    if (png_crc_finish(png_ptr, 0))
  627.       return;
  628.  
  629.    png_set_cHRM(png_ptr, info_ptr,
  630.       white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
  631. }
  632. #endif
  633.  
  634. #if defined(PNG_READ_tRNS_SUPPORTED)
  635. void
  636. png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  637. {
  638.    png_debug(1, "in png_handle_tRNS\n");
  639.  
  640.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  641.       png_error(png_ptr, "Missing IHDR before tRNS");
  642.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  643.    {
  644.       png_warning(png_ptr, "Invalid tRNS after IDAT");
  645.       png_crc_finish(png_ptr, length);
  646.       return;
  647.    }
  648.    else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
  649.    {
  650.       png_warning(png_ptr, "Duplcate tRNS chunk");
  651.       png_crc_finish(png_ptr, length);
  652.       return;
  653.    }
  654.  
  655.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  656.    {
  657.       if (!(png_ptr->mode & PNG_HAVE_PLTE))
  658.       {
  659.          /* Should be an error, but we can cope with it */
  660.          png_warning(png_ptr, "Missing PLTE before tRNS");
  661.       }
  662.       else if (length > png_ptr->num_palette)
  663.       {
  664.          png_warning(png_ptr, "Incorrect tRNS chunk length");
  665.          png_crc_finish(png_ptr, length);
  666.          return;
  667.       }
  668.  
  669.       png_ptr->trans = (png_bytep)png_malloc(png_ptr, length);
  670.       png_ptr->flags |= PNG_FLAG_FREE_TRANS;
  671.       png_crc_read(png_ptr, png_ptr->trans, (png_size_t)length);
  672.       png_ptr->num_trans = (png_uint_16)length;
  673.    }
  674.    else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
  675.    {
  676.       png_byte buf[6];
  677.  
  678.       if (length != 6)
  679.       {
  680.          png_warning(png_ptr, "Incorrect tRNS chunk length");
  681.          png_crc_finish(png_ptr, length);
  682.          return;
  683.       }
  684.  
  685.       png_crc_read(png_ptr, buf, (png_size_t)length);
  686.       png_ptr->num_trans = 3;
  687.       png_ptr->trans_values.red = png_get_uint_16(buf);
  688.       png_ptr->trans_values.green = png_get_uint_16(buf + 2);
  689.       png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
  690.    }
  691.    else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  692.    {
  693.       png_byte buf[6];
  694.  
  695.       if (length != 2)
  696.       {
  697.          png_warning(png_ptr, "Incorrect tRNS chunk length");
  698.          png_crc_finish(png_ptr, length);
  699.          return;
  700.       }
  701.  
  702.       png_crc_read(png_ptr, buf, 2);
  703.       png_ptr->num_trans = 1;
  704.       png_ptr->trans_values.gray = png_get_uint_16(buf);
  705.    }
  706.    else
  707.    {
  708.       png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
  709.       png_crc_finish(png_ptr, length);
  710.       return;
  711.    }
  712.  
  713.    if (png_crc_finish(png_ptr, 0))
  714.       return;
  715.  
  716.    png_set_tRNS(png_ptr, info_ptr, png_ptr->trans, png_ptr->num_trans,
  717.       &(png_ptr->trans_values));
  718. }
  719. #endif
  720.  
  721. #if defined(PNG_READ_bKGD_SUPPORTED)
  722. void
  723. png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  724. {
  725.    png_size_t truelen;
  726.    png_byte buf[6];
  727.  
  728.    png_debug(1, "in png_handle_bKGD\n");
  729.  
  730.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  731.       png_error(png_ptr, "Missing IHDR before bKGD");
  732.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  733.    {
  734.       png_warning(png_ptr, "Invalid bKGD after IDAT");
  735.       png_crc_finish(png_ptr, length);
  736.       return;
  737.    }
  738.    else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
  739.             !(png_ptr->mode & PNG_HAVE_PLTE))
  740.    {
  741.       png_warning(png_ptr, "Missing PLTE before bKGD");
  742.       png_crc_finish(png_ptr, length);
  743.       return;
  744.    }
  745.    else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_bKGD)
  746.    {
  747.       png_warning(png_ptr, "Duplicate bKGD chunk");
  748.       png_crc_finish(png_ptr, length);
  749.       return;
  750.    }
  751.  
  752.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  753.       truelen = 1;
  754.    else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
  755.       truelen = 6;
  756.    else
  757.       truelen = 2;
  758.  
  759.    if (length != truelen)
  760.    {
  761.       png_warning(png_ptr, "Incorrect bKGD chunk length");
  762.       png_crc_finish(png_ptr, length);
  763.       return;
  764.    }
  765.  
  766.    png_crc_read(png_ptr, buf, truelen);
  767.    if (png_crc_finish(png_ptr, 0))
  768.       return;
  769.  
  770.    /* We convert the index value into RGB components so that we can allow
  771.     * arbitrary RGB values for background when we have transparency, and
  772.     * so it is easy to determine the RGB values of the background color
  773.     * from the info_ptr struct. */
  774.    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  775.    {
  776.       png_ptr->background.index = buf[0];
  777.       png_ptr->background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
  778.       png_ptr->background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
  779.       png_ptr->background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
  780.    }
  781.    else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
  782.    {
  783.       png_ptr->background.red =
  784.       png_ptr->background.green =
  785.       png_ptr->background.blue =
  786.       png_ptr->background.gray = png_get_uint_16(buf);
  787.    }
  788.    else
  789.    {
  790.       png_ptr->background.red = png_get_uint_16(buf);
  791.       png_ptr->background.green = png_get_uint_16(buf + 2);
  792.       png_ptr->background.blue = png_get_uint_16(buf + 4);
  793.    }
  794.  
  795.    png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
  796. }
  797. #endif
  798.  
  799. #if defined(PNG_READ_hIST_SUPPORTED)
  800. void
  801. png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  802. {
  803.    int num, i;
  804.  
  805.    png_debug(1, "in png_handle_hIST\n");
  806.  
  807.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  808.       png_error(png_ptr, "Missing IHDR before hIST");
  809.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  810.    {
  811.       png_warning(png_ptr, "Invalid hIST after IDAT");
  812.       png_crc_finish(png_ptr, length);
  813.       return;
  814.    }
  815.    else if (!(png_ptr->mode & PNG_HAVE_PLTE))
  816.    {
  817.       png_warning(png_ptr, "Missing PLTE before hIST");
  818.       png_crc_finish(png_ptr, length);
  819.       return;
  820.    }
  821.    else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_hIST)
  822.    {
  823.       png_warning(png_ptr, "Duplicate hIST chunk");
  824.       png_crc_finish(png_ptr, length);
  825.       return;
  826.    }
  827.  
  828.    if (length != (png_uint_32)(2 * png_ptr->num_palette))
  829.    {
  830.       png_warning(png_ptr, "Incorrect hIST chunk length");
  831.       png_crc_finish(png_ptr, length);
  832.       return;
  833.    }
  834.  
  835.    num = (int)length / 2;
  836.    png_ptr->hist = (png_uint_16p)png_malloc(png_ptr,
  837.       num * sizeof (png_uint_16));
  838.    png_ptr->flags |= PNG_FLAG_FREE_HIST;
  839.    for (i = 0; i < num; i++)
  840.    {
  841.       png_byte buf[2];
  842.  
  843.       png_crc_read(png_ptr, buf, 2);
  844.       png_ptr->hist[i] = png_get_uint_16(buf);
  845.    }
  846.  
  847.    if (png_crc_finish(png_ptr, 0))
  848.       return;
  849.  
  850.    png_set_hIST(png_ptr, info_ptr, png_ptr->hist);
  851. }
  852. #endif
  853.  
  854. #if defined(PNG_READ_pHYs_SUPPORTED)
  855. void
  856. png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  857. {
  858.    png_byte buf[9];
  859.    png_uint_32 res_x, res_y;
  860.    int unit_type;
  861.  
  862.    png_debug(1, "in png_handle_pHYs\n");
  863.  
  864.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  865.       png_error(png_ptr, "Missing IHDR before pHYS");
  866.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  867.    {
  868.       png_warning(png_ptr, "Invalid pHYS after IDAT");
  869.       png_crc_finish(png_ptr, length);
  870.       return;
  871.    }
  872.    else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs)
  873.    {
  874.       png_warning(png_ptr, "Duplicate pHYS chunk");
  875.       png_crc_finish(png_ptr, length);
  876.       return;
  877.    }
  878.  
  879.    if (length != 9)
  880.    {
  881.       png_warning(png_ptr, "Incorrect pHYs chunk length");
  882.       png_crc_finish(png_ptr, length);
  883.       return;
  884.    }
  885.  
  886.    png_crc_read(png_ptr, buf, 9);
  887.    if (png_crc_finish(png_ptr, 0))
  888.       return;
  889.  
  890.    res_x = png_get_uint_32(buf);
  891.    res_y = png_get_uint_32(buf + 4);
  892.    unit_type = buf[8];
  893.    png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
  894. }
  895. #endif
  896.  
  897. #if defined(PNG_READ_oFFs_SUPPORTED)
  898. void
  899. png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  900. {
  901.    png_byte buf[9];
  902.    png_uint_32 offset_x, offset_y;
  903.    int unit_type;
  904.  
  905.    png_debug(1, "in png_handle_oFFs\n");
  906.  
  907.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  908.       png_error(png_ptr, "Missing IHDR before oFFs");
  909.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  910.    {
  911.       png_warning(png_ptr, "Invalid oFFs after IDAT");
  912.       png_crc_finish(png_ptr, length);
  913.       return;
  914.    }
  915.    else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_oFFs)
  916.    {
  917.       png_warning(png_ptr, "Duplicate oFFs chunk");
  918.       png_crc_finish(png_ptr, length);
  919.       return;
  920.    }
  921.  
  922.    if (length != 9)
  923.    {
  924.       png_warning(png_ptr, "Incorrect oFFs chunk length");
  925.       png_crc_finish(png_ptr, length);
  926.       return;
  927.    }
  928.  
  929.    png_crc_read(png_ptr, buf, 9);
  930.    if (png_crc_finish(png_ptr, 0))
  931.       return;
  932.  
  933.    offset_x = png_get_uint_32(buf);
  934.    offset_y = png_get_uint_32(buf + 4);
  935.    unit_type = buf[8];
  936.    png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
  937. }
  938. #endif
  939.  
  940. #if defined(PNG_READ_pCAL_SUPPORTED)
  941. /* read the pCAL chunk (png-scivis-19970203) */
  942. void
  943. png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  944. {
  945.    png_charp purpose;
  946.    png_int_32 X0, X1;
  947.    png_byte type, nparams;
  948.    png_charp buf, units, endptr;
  949.    png_charpp params;
  950.    int i;
  951.  
  952.    png_debug(1, "in png_handle_pCAL\n");
  953.  
  954.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  955.       png_error(png_ptr, "Missing IHDR before pCAL");
  956.    else if (png_ptr->mode & PNG_HAVE_IDAT)
  957.    {
  958.       png_warning(png_ptr, "Invalid pCAL after IDAT");
  959.       png_crc_finish(png_ptr, length);
  960.       return;
  961.    }
  962.    else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_pCAL)
  963.    {
  964.       png_warning(png_ptr, "Duplicate pCAL chunk");
  965.       png_crc_finish(png_ptr, length);
  966.       return;
  967.    }
  968.  
  969.    png_debug1(2, "Allocating and reading pCAL chunk data (%d bytes)\n",
  970.       length + 1);
  971.    purpose = (png_charp)png_malloc(png_ptr, length + 1);
  972.    png_crc_read(png_ptr, (png_bytep)purpose, (png_size_t)length);
  973.  
  974.    if (png_crc_finish(png_ptr, 0))
  975.    {
  976.       png_free(png_ptr, purpose);
  977.       return;
  978.    }
  979.  
  980.    purpose[length] = '\0'; /* null terminate the last string */
  981.  
  982.    png_debug(3, "Finding end of pCAL purpose string\n");
  983.    for (buf = purpose; *buf != '\0'; buf++)
  984.       /* empty loop */;
  985.  
  986.    endptr = purpose + length;
  987.  
  988.    /* We need to have at least 12 bytes after the purpose string
  989.       in order to get the parameter information. */
  990.    if (endptr <= buf + 12)
  991.    {
  992.       png_warning(png_ptr, "Invalid pCAL data");
  993.       png_free(png_ptr, purpose);
  994.       return;
  995.    }
  996.  
  997.    png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
  998.    X0 = png_get_int_32((png_bytep)buf+1);
  999.    X1 = png_get_int_32((png_bytep)buf+5);
  1000.    type = buf[9];
  1001.    nparams = buf[10];
  1002.    units = buf + 11;
  1003.  
  1004.    png_debug(3, "Checking pCAL equation type and number of parameters\n");
  1005.    /* Check that we have the right number of parameters for known
  1006.       equation types. */
  1007.    if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
  1008.        (type == PNG_EQUATION_BASE_E && nparams != 3) ||
  1009.        (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
  1010.        (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
  1011.    {
  1012.       png_warning(png_ptr, "Invalid pCAL parameters for equation type");
  1013.       png_free(png_ptr, purpose);
  1014.       return;
  1015.    }
  1016.    else if (type >= PNG_EQUATION_LAST)
  1017.    {
  1018.       png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
  1019.    }
  1020.  
  1021.    /* Empty loop to move past the units string. */
  1022.    for (buf = units; *buf != '\0'; buf++);
  1023.  
  1024.    png_debug(3, "Allocating pCAL parameters array\n");
  1025.    params = (png_charpp)png_malloc(png_ptr, nparams*sizeof(png_charp)) ;
  1026.  
  1027.    /* Get pointers to the start of each parameter string. */
  1028.    for (i = 0; i < nparams; i++)
  1029.    {
  1030.       buf++; /* Skip the null string terminator from previous parameter. */
  1031.  
  1032.       png_debug1(3, "Reading pCAL parameter %d\n", i);
  1033.       /* Empty loop to move past each paramter string */
  1034.       for (params[i] = buf; *buf != '\0' && buf <= endptr; buf++);
  1035.  
  1036.       /* Make sure we haven't run out of data yet */
  1037.       if (buf > endptr)
  1038.       {
  1039.          png_warning(png_ptr, "Invalid pCAL data");
  1040.          png_free(png_ptr, purpose);
  1041.          png_free(png_ptr, params);
  1042.          return;
  1043.       }
  1044.    }
  1045.  
  1046.    png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
  1047.       units, params);
  1048.  
  1049.    png_free(png_ptr, purpose);
  1050.    png_free(png_ptr, params);
  1051. }
  1052. #endif
  1053.  
  1054. #if defined(PNG_READ_tIME_SUPPORTED)
  1055. void
  1056. png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1057. {
  1058.    png_byte buf[7];
  1059.    png_time mod_time;
  1060.  
  1061.    png_debug(1, "in png_handle_tIME\n");
  1062.  
  1063.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1064.       png_error(png_ptr, "Out of place tIME chunk");
  1065.    else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tIME)
  1066.    {
  1067.       png_warning(png_ptr, "Duplicate tIME chunk");
  1068.       png_crc_finish(png_ptr, length);
  1069.       return;
  1070.    }
  1071.  
  1072.    if (png_ptr->mode & PNG_HAVE_IDAT)
  1073.       png_ptr->mode |= PNG_AFTER_IDAT;
  1074.  
  1075.    if (length != 7)
  1076.    {
  1077.       png_warning(png_ptr, "Incorrect tIME chunk length");
  1078.       png_crc_finish(png_ptr, length);
  1079.       return;
  1080.    }
  1081.  
  1082.    png_crc_read(png_ptr, buf, 7);
  1083.    if (png_crc_finish(png_ptr, 0))
  1084.       return;
  1085.  
  1086.    mod_time.second = buf[6];
  1087.    mod_time.minute = buf[5];
  1088.    mod_time.hour = buf[4];
  1089.    mod_time.day = buf[3];
  1090.    mod_time.month = buf[2];
  1091.    mod_time.year = png_get_uint_16(buf);
  1092.  
  1093.    png_set_tIME(png_ptr, info_ptr, &mod_time);
  1094. }
  1095. #endif
  1096.  
  1097. #if defined(PNG_READ_tEXt_SUPPORTED)
  1098. /* Note: this does not properly handle chunks that are > 64K under DOS */
  1099. void
  1100. png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1101. {
  1102.    png_textp text_ptr;
  1103.    png_charp key;
  1104.    png_charp text;
  1105.    png_uint_32 skip = 0;
  1106.  
  1107.    png_debug(1, "in png_handle_tEXt\n");
  1108.  
  1109.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1110.       png_error(png_ptr, "Missing IHDR before tEXt");
  1111.  
  1112.    if (png_ptr->mode & PNG_HAVE_IDAT)
  1113.       png_ptr->mode |= PNG_AFTER_IDAT;
  1114.  
  1115. #ifdef PNG_MAX_MALLOC_64K
  1116.    if (length > 65535L)
  1117.    {
  1118.       png_warning(png_ptr, "tEXt chunk too large to fit in memory");
  1119.       skip = length - 65535L;
  1120.       length = 65535L;
  1121.    }
  1122. #endif
  1123.  
  1124.    key = (png_charp)png_malloc(png_ptr, length + 1);
  1125.    png_crc_read(png_ptr, (png_bytep)key, (png_size_t)length);
  1126.  
  1127.    if (png_crc_finish(png_ptr, skip))
  1128.    {
  1129.       png_free(png_ptr, key);
  1130.       return;
  1131.    }
  1132.  
  1133.    key[length] = '\0';
  1134.  
  1135.    for (text = key; *text; text++)
  1136.       /* empty loop to find end of key */ ;
  1137.  
  1138.    if (text != key + (png_size_t)length)
  1139.       text++;
  1140.  
  1141.    text_ptr = (png_textp)png_malloc(png_ptr, sizeof(png_text));
  1142.    text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
  1143.    text_ptr->key = key;
  1144.    text_ptr->text = text;
  1145.  
  1146.    png_set_text(png_ptr, info_ptr, text_ptr, 1);
  1147.  
  1148.    png_free(png_ptr, text_ptr);
  1149. }
  1150. #endif
  1151.  
  1152. #if defined(PNG_READ_zTXt_SUPPORTED)
  1153. /* note: this does not correctly handle chunks that are > 64K under DOS */
  1154. void
  1155. png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1156. {
  1157.    static char msg[] = "Error decoding zTXt chunk";
  1158.    png_textp text_ptr;
  1159.    png_charp key;
  1160.    png_charp text;
  1161.    int comp_type = PNG_TEXT_COMPRESSION_NONE;
  1162.  
  1163.    png_debug(1, "in png_handle_zTXt\n");
  1164.  
  1165.    if (!(png_ptr->mode & PNG_HAVE_IHDR))
  1166.       png_error(png_ptr, "Missing IHDR before zTXt");
  1167.  
  1168.    if (png_ptr->mode & PNG_HAVE_IDAT)
  1169.       png_ptr->mode |= PNG_AFTER_IDAT;
  1170.  
  1171. #ifdef PNG_MAX_MALLOC_64K
  1172.    /* We will no doubt have problems with chunks even half this size, but
  1173.       there is no hard and fast rule to tell us where to stop. */
  1174.    if (length > 65535L)
  1175.    {
  1176.      png_warning(png_ptr,"zTXt chunk too large to fit in memory");
  1177.      png_crc_finish(png_ptr, length);
  1178.      return;
  1179.    }
  1180. #endif
  1181.  
  1182.    key = (png_charp)png_malloc(png_ptr, length + 1);
  1183.    png_crc_read(png_ptr, (png_bytep)key, (png_size_t)length);
  1184.    if (png_crc_finish(png_ptr, 0))
  1185.    {
  1186.       png_free(png_ptr, key);
  1187.       return;
  1188.    }
  1189.  
  1190.    key[length] = '\0';
  1191.  
  1192.    for (text = key; *text; text++)
  1193.       /* empty loop */ ;
  1194.  
  1195.    /* zTXt must have some text after the keyword */
  1196.    if (text == key + (png_size_t)length)
  1197.    {
  1198.       png_warning(png_ptr, "Zero length zTXt chunk");
  1199.    }
  1200.    else if ((comp_type = *(++text)) == PNG_TEXT_COMPRESSION_zTXt)
  1201.    {
  1202.       png_size_t text_size, key_size;
  1203.       text++;
  1204.  
  1205.       png_ptr->zstream.next_in = (png_bytep)text;
  1206.       png_ptr->zstream.avail_in = (uInt)(length - (text - key));
  1207.       png_ptr->zstream.next_out = png_ptr->zbuf;
  1208.       png_ptr->zstream.avail_out = png_ptr->zbuf_size;
  1209.  
  1210.       key_size = text - key;
  1211.       text_size = 0;
  1212.       text = NULL;
  1213.  
  1214.       while (png_ptr->zstream.avail_in)
  1215.       {
  1216.          int ret;
  1217.  
  1218.          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  1219.          if (ret != Z_OK && ret != Z_STREAM_END)
  1220.          {
  1221.             if (png_ptr->zstream.msg != NULL)
  1222.                png_warning(png_ptr, png_ptr->zstream.msg);
  1223.             else
  1224.                png_warning(png_ptr, msg);
  1225.             inflateReset(&png_ptr->zstream);
  1226.             png_ptr->zstream.avail_in = 0;
  1227.  
  1228.             if (text ==  NULL)
  1229.             {
  1230.                text_size = key_size + sizeof(msg) + 1;
  1231.                text = (png_charp)png_malloc(png_ptr, text_size);
  1232.                png_memcpy(text, key, key_size);
  1233.             }
  1234.  
  1235.             text[text_size - 1] = '\0';
  1236.  
  1237.             /* Copy what we can of the error message into the text chunk */
  1238.             text_size = length - (text - key) - 1;
  1239.             text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
  1240.             png_memcpy(text + key_size, msg, text_size + 1);
  1241.             break;
  1242.          }
  1243.          if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
  1244.          {
  1245.             if (text == NULL)
  1246.             {
  1247.                text = (png_charp)png_malloc(png_ptr,
  1248.                   png_ptr->zbuf_size - png_ptr->zstream.avail_out +
  1249.                      key_size + 1);
  1250.                png_memcpy(text + key_size, png_ptr->zbuf,
  1251.                   png_ptr->zbuf_size - png_ptr->zstream.avail_out);
  1252.                png_memcpy(text, key, key_size);
  1253.                text_size = key_size + png_ptr->zbuf_size -
  1254.                   png_ptr->zstream.avail_out;
  1255.                *(text + text_size) = '\0';
  1256.             }
  1257.             else
  1258.             {
  1259.                png_charp tmp;
  1260.  
  1261.                tmp = text;
  1262.                text = png_malloc(png_ptr, text_size +
  1263.                   png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1);
  1264.                png_memcpy(text, tmp, text_size);
  1265.                png_free(png_ptr, tmp);
  1266.                png_memcpy(text + text_size, png_ptr->zbuf,
  1267.                   (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
  1268.                text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
  1269.                *(text + text_size) = '\0';
  1270.             }
  1271.             if (ret != Z_STREAM_END)
  1272.             {
  1273.                png_ptr->zstream.next_out = png_ptr->zbuf;
  1274.                png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
  1275.             }
  1276.             else
  1277.             {
  1278.                break;
  1279.             }
  1280.          }
  1281.       }
  1282.  
  1283.       inflateReset(&png_ptr->zstream);
  1284.       png_ptr->zstream.avail_in = 0;
  1285.  
  1286.       png_free(png_ptr, key);
  1287.       key = text;
  1288.       text += key_size;
  1289.       text_size -= key_size;
  1290.    }
  1291.    else /* if (comp_type >= PNG_TEXT_COMPRESSION_LAST) */
  1292.    {
  1293.       png_size_t text_size;
  1294.       char umsg[50];
  1295.  
  1296.       sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
  1297.       png_warning(png_ptr, umsg);
  1298.  
  1299.       /* Copy what we can of the error message into the text chunk */
  1300.       text_size = (png_size_t)length - (text - key) - 1;
  1301.       text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
  1302.       png_memcpy(text, msg, text_size + 1);
  1303.    }
  1304.  
  1305.    text_ptr = (png_textp)png_malloc(png_ptr, sizeof(png_text));
  1306.    text_ptr->compression = comp_type;
  1307.    text_ptr->key = key;
  1308.    text_ptr->text = text;
  1309.  
  1310.    png_set_text(png_ptr, info_ptr, text_ptr, 1);
  1311.  
  1312.    png_free(png_ptr, text_ptr);
  1313. }
  1314. #endif
  1315.  
  1316. /* This function is called when we haven't found a handler for a
  1317.    chunk.  If there isn't a problem with the chunk itself (ie bad
  1318.    chunk name, CRC, or a critical chunk), the chunk is silently ignored. */
  1319. void
  1320. png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
  1321. {
  1322.    png_debug(1, "in png_handle_unknown\n");
  1323.  
  1324.    /* In the future we can have code here that calls user-supplied
  1325.     * callback functions for unknown chunks before they are ignored or
  1326.     * cause an error.
  1327.     */
  1328.    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
  1329.  
  1330.    if (!(png_ptr->chunk_name[0] & 0x20))
  1331.    {
  1332.       char msg[40];
  1333.  
  1334.       sprintf(msg, "Unknown critical chunk %s", png_ptr->chunk_name);
  1335.       png_error(png_ptr, msg);
  1336.    }
  1337.  
  1338.    if (png_ptr->mode & PNG_HAVE_IDAT)
  1339.       png_ptr->mode |= PNG_AFTER_IDAT;
  1340.  
  1341.    png_crc_finish(png_ptr, length);
  1342. }
  1343.  
  1344. /* This function is called to verify that a chunk name is valid.
  1345.    This function can't have the "critical chunk check" incorporated
  1346.    into it, since in the future we will need to be able to call user
  1347.    functions to handle unknown critical chunks after we check that
  1348.    the chunk name itself is valid. */
  1349.  
  1350. #define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
  1351.  
  1352. void
  1353. png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
  1354. {
  1355.    png_debug(1, "in png_check_chunk_name\n");
  1356.    if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
  1357.        isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
  1358.    {
  1359.       char msg[45];
  1360.  
  1361.       sprintf(msg, "Invalid chunk type 0x%02X 0x%02X 0x%02X 0x%02X",
  1362.          chunk_name[0], chunk_name[1], chunk_name[2], chunk_name[3]);
  1363.       png_error(png_ptr, msg);
  1364.    }
  1365. }
  1366.  
  1367. /* Combines the row recently read in with the previous row.
  1368.    This routine takes care of alpha and transparency if requested.
  1369.    This routine also handles the two methods of progressive display
  1370.    of interlaced images, depending on the mask value.
  1371.    The mask value describes which pixels are to be combined with
  1372.    the row.  The pattern always repeats every 8 pixels, so just 8
  1373.    bits are needed.  A one indicates the pixels is to be combined,
  1374.    a zero indicates the pixel is to be skipped.  This is in addition
  1375.    to any alpha or transparency value associated with the pixel.  If
  1376.    you want all pixels to be combined, pass 0xff (255) in mask.  */
  1377. void
  1378. png_combine_row(png_structp png_ptr, png_bytep row,
  1379.    int mask)
  1380. {
  1381.    png_debug(1,"in png_combine_row\n");
  1382.    if (mask == 0xff)
  1383.    {
  1384.       png_memcpy(row, png_ptr->row_buf + 1,
  1385.          (png_size_t)((png_ptr->width *
  1386.          png_ptr->row_info.pixel_depth + 7) >> 3));
  1387.    }
  1388.    else
  1389.    {
  1390.       switch (png_ptr->row_info.pixel_depth)
  1391.       {
  1392.          case 1:
  1393.          {
  1394.             png_bytep sp;
  1395.             png_bytep dp;
  1396.             int s_inc, s_start, s_end;
  1397.             int m;
  1398.             int shift;
  1399.             png_uint_32 i;
  1400.  
  1401.             sp = png_ptr->row_buf + 1;
  1402.             dp = row;
  1403.             m = 0x80;
  1404. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  1405.             if (png_ptr->transformations & PNG_PACKSWAP)
  1406.             {
  1407.                 s_start = 0;
  1408.                 s_end = 7;
  1409.                 s_inc = 1;
  1410.             }
  1411.             else
  1412. #endif
  1413.             {
  1414.                 s_start = 7;
  1415.                 s_end = 0;
  1416.                 s_inc = -1;
  1417.             }
  1418.  
  1419.             shift = s_start;
  1420.  
  1421.             for (i = 0; i < png_ptr->width; i++)
  1422.             {
  1423.                if (m & mask)
  1424.                {
  1425.                   int value;
  1426.  
  1427.                   value = (*sp >> shift) & 0x1;
  1428.                   *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
  1429.                   *dp |= (png_byte)(value << shift);
  1430.                }
  1431.  
  1432.                if (shift == s_end)
  1433.                {
  1434.                   shift = s_start;
  1435.                   sp++;
  1436.                   dp++;
  1437.                }
  1438.                else
  1439.                   shift += s_inc;
  1440.  
  1441.                if (m == 1)
  1442.                   m = 0x80;
  1443.                else
  1444.                   m >>= 1;
  1445.             }
  1446.             break;
  1447.          }
  1448.          case 2:
  1449.          {
  1450.             png_bytep sp;
  1451.             png_bytep dp;
  1452.             int s_start, s_end, s_inc;
  1453.             int m;
  1454.             int shift;
  1455.             png_uint_32 i;
  1456.             int value;
  1457.  
  1458.             sp = png_ptr->row_buf + 1;
  1459.             dp = row;
  1460.             m = 0x80;
  1461. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  1462.             if (png_ptr->transformations & PNG_PACKSWAP)
  1463.             {
  1464.                s_start = 0;
  1465.                s_end = 6;
  1466.                s_inc = 2;
  1467.             }
  1468.             else
  1469. #endif
  1470.             {
  1471.                s_start = 6;
  1472.                s_end = 0;
  1473.                s_inc = -2;
  1474.             }
  1475.  
  1476.             shift = s_start;
  1477.  
  1478.             for (i = 0; i < png_ptr->width; i++)
  1479.             {
  1480.                if (m & mask)
  1481.                {
  1482.                   value = (*sp >> shift) & 0x3;
  1483.                   *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
  1484.                   *dp |= (png_byte)(value << shift);
  1485.                }
  1486.  
  1487.                if (shift == s_end)
  1488.                {
  1489.                   shift = s_start;
  1490.                   sp++;
  1491.                   dp++;
  1492.                }
  1493.                else
  1494.                   shift += s_inc;
  1495.                if (m == 1)
  1496.                   m = 0x80;
  1497.                else
  1498.                   m >>= 1;
  1499.             }
  1500.             break;
  1501.          }
  1502.          case 4:
  1503.          {
  1504.             png_bytep sp;
  1505.             png_bytep dp;
  1506.             int s_start, s_end, s_inc;
  1507.             int m;
  1508.             int shift;
  1509.             png_uint_32 i;
  1510.             int value;
  1511.  
  1512.             sp = png_ptr->row_buf + 1;
  1513.             dp = row;
  1514.             m = 0x80;
  1515. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  1516.             if (png_ptr->transformations & PNG_PACKSWAP)
  1517.             {
  1518.                s_start = 0;
  1519.                s_end = 4;
  1520.                s_inc = 4;
  1521.             }
  1522.             else
  1523. #endif
  1524.             {
  1525.                s_start = 4;
  1526.                s_end = 0;
  1527.                s_inc = -4;
  1528.             }
  1529.             shift = s_start;
  1530.  
  1531.             for (i = 0; i < png_ptr->width; i++)
  1532.             {
  1533.                if (m & mask)
  1534.                {
  1535.                   value = (*sp >> shift) & 0xf;
  1536.                   *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
  1537.                   *dp |= (png_byte)(value << shift);
  1538.                }
  1539.  
  1540.                if (shift == s_end)
  1541.                {
  1542.                   shift = s_start;
  1543.                   sp++;
  1544.                   dp++;
  1545.                }
  1546.                else
  1547.                   shift += s_inc;
  1548.                if (m == 1)
  1549.                   m = 0x80;
  1550.                else
  1551.                   m >>= 1;
  1552.             }
  1553.             break;
  1554.          }
  1555.          default:
  1556.          {
  1557.             png_bytep sp;
  1558.             png_bytep dp;
  1559.             png_size_t pixel_bytes;
  1560.             png_uint_32 i;
  1561.             png_byte m;
  1562.  
  1563.             pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
  1564.  
  1565.             sp = png_ptr->row_buf + 1;
  1566.             dp = row;
  1567.             m = 0x80;
  1568.             for (i = 0; i < png_ptr->width; i++)
  1569.             {
  1570.                if (m & mask)
  1571.                {
  1572.                   png_memcpy(dp, sp, pixel_bytes);
  1573.                }
  1574.  
  1575.                sp += pixel_bytes;
  1576.                dp += pixel_bytes;
  1577.  
  1578.                if (m == 1)
  1579.                   m = 0x80;
  1580.                else
  1581.                   m >>= 1;
  1582.             }
  1583.             break;
  1584.          }
  1585.       }
  1586.    }
  1587. }
  1588.  
  1589. #if defined(PNG_READ_INTERLACING_SUPPORTED)
  1590. void
  1591. png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
  1592.    png_uint_32 transformations)
  1593. {
  1594.    png_debug(1,"in png_do_read_interlace\n");
  1595.    if (row != NULL && row_info != NULL)
  1596.    {
  1597.       png_uint_32 final_width;
  1598.  
  1599.       final_width = row_info->width * png_pass_inc[pass];
  1600.  
  1601.       switch (row_info->pixel_depth)
  1602.       {
  1603.          case 1:
  1604.          {
  1605.             png_bytep sp, dp;
  1606.             int sshift, dshift;
  1607.             int s_start, s_end, s_inc;
  1608.             png_byte v;
  1609.             png_uint_32 i;
  1610.             int j;
  1611.  
  1612.             sp = row + (png_size_t)((row_info->width - 1) >> 3);
  1613.             dp = row + (png_size_t)((final_width - 1) >> 3);
  1614. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  1615.             if (transformations & PNG_PACKSWAP)
  1616.             {
  1617.                 sshift = (int)((row_info->width + 7) & 7);
  1618.                 dshift = (int)((final_width + 7) & 7);
  1619.                 s_start = 7;
  1620.                 s_end = 0;
  1621.                 s_inc = -1;
  1622.             }
  1623.             else
  1624. #endif
  1625.             {
  1626.                 sshift = 7 - (int)((row_info->width + 7) & 7);
  1627.                 dshift = 7 - (int)((final_width + 7) & 7);
  1628.                 s_start = 0;
  1629.                 s_end = 7;
  1630.                 s_inc = 1;
  1631.             }
  1632.  
  1633.             for (i = row_info->width; i; i--)
  1634.             {
  1635.                v = (png_byte)((*sp >> sshift) & 0x1);
  1636.                for (j = 0; j < png_pass_inc[pass]; j++)
  1637.                {
  1638.                   *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
  1639.                   *dp |= (png_byte)(v << dshift);
  1640.                   if (dshift == s_end)
  1641.                   {
  1642.                      dshift = s_start;
  1643.                      dp--;
  1644.                   }
  1645.                   else
  1646.                      dshift += s_inc;
  1647.                }
  1648.                if (sshift == s_end)
  1649.                {
  1650.                   sshift = s_start;
  1651.                   sp--;
  1652.                }
  1653.                else
  1654.                   sshift += s_inc;
  1655.             }
  1656.             break;
  1657.          }
  1658.          case 2:
  1659.          {
  1660.             png_bytep sp, dp;
  1661.             int sshift, dshift;
  1662.             int s_start, s_end, s_inc;
  1663.             png_uint_32 i;
  1664.  
  1665.             sp = row + (png_size_t)((row_info->width - 1) >> 2);
  1666.             dp = row + (png_size_t)((final_width - 1) >> 2);
  1667. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  1668.             if (transformations & PNG_PACKSWAP)
  1669.             {
  1670.                sshift = (png_size_t)(((row_info->width + 3) & 3) << 1);
  1671.                dshift = (png_size_t)(((final_width + 3) & 3) << 1);
  1672.                s_start = 6;
  1673.                s_end = 0;
  1674.                s_inc = -2;
  1675.             }
  1676.             else
  1677. #endif
  1678.             {
  1679.                sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1);
  1680.                dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1);
  1681.                s_start = 0;
  1682.                s_end = 6;
  1683.                s_inc = 2;
  1684.             }
  1685.  
  1686.             for (i = row_info->width; i; i--)
  1687.             {
  1688.                png_byte v;
  1689.                int j;
  1690.  
  1691.                v = (png_byte)((*sp >> sshift) & 0x3);
  1692.                for (j = 0; j < png_pass_inc[pass]; j++)
  1693.                {
  1694.                   *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
  1695.                   *dp |= (png_byte)(v << dshift);
  1696.                   if (dshift == s_end)
  1697.                   {
  1698.                      dshift = s_start;
  1699.                      dp--;
  1700.                   }
  1701.                   else
  1702.                      dshift += s_inc;
  1703.                }
  1704.                if (sshift == s_end)
  1705.                {
  1706.                   sshift = s_start;
  1707.                   sp--;
  1708.                }
  1709.                else
  1710.                   sshift += s_inc;
  1711.             }
  1712.             break;
  1713.          }
  1714.          case 4:
  1715.          {
  1716.             png_bytep sp, dp;
  1717.             int sshift, dshift;
  1718.             int s_start, s_end, s_inc;
  1719.             png_uint_32 i;
  1720.  
  1721.             sp = row + (png_size_t)((row_info->width - 1) >> 1);
  1722.             dp = row + (png_size_t)((final_width - 1) >> 1);
  1723. #if defined(PNG_READ_PACKSWAP_SUPPORTED)
  1724.             if (transformations & PNG_PACKSWAP)
  1725.             {
  1726.                sshift = (png_size_t)(((row_info->width + 1) & 1) << 2);
  1727.                dshift = (png_size_t)(((final_width + 1) & 1) << 2);
  1728.                s_start = 4;
  1729.                s_end = 0;
  1730.                s_inc = -4;
  1731.             }
  1732.             else
  1733. #endif
  1734.             {
  1735.                sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2);
  1736.                dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2);
  1737.                s_start = 0;
  1738.                s_end = 4;
  1739.                s_inc = 4;
  1740.             }
  1741.  
  1742.             for (i = row_info->width; i; i--)
  1743.             {
  1744.                png_byte v;
  1745.                int j;
  1746.  
  1747.                v = (png_byte)((*sp >> sshift) & 0xf);
  1748.                for (j = 0; j < png_pass_inc[pass]; j++)
  1749.                {
  1750.                   *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
  1751.                   *dp |= (png_byte)(v << dshift);
  1752.                   if (dshift == s_end)
  1753.                   {
  1754.                      dshift = s_start;
  1755.                      dp--;
  1756.                   }
  1757.                   else
  1758.                      dshift += s_inc;
  1759.                }
  1760.                if (sshift == s_end)
  1761.                {
  1762.                   sshift = s_start;
  1763.                   sp--;
  1764.                }
  1765.                else
  1766.                   sshift += s_inc;
  1767.             }
  1768.             break;
  1769.          }
  1770.          default:
  1771.          {
  1772.             png_bytep sp, dp;
  1773.             png_uint_32 i;
  1774.             png_size_t pixel_bytes;
  1775.  
  1776.             pixel_bytes = (row_info->pixel_depth >> 3);
  1777.  
  1778.             sp = row + (row_info->width - 1) * pixel_bytes;
  1779.             dp = row + (final_width - 1) * pixel_bytes;
  1780.             for (i = row_info->width; i; i--)
  1781.             {
  1782.                png_byte v[8];
  1783.                int j;
  1784.  
  1785.                png_memcpy(v, sp, pixel_bytes);
  1786.                for (j = 0; j < png_pass_inc[pass]; j++)
  1787.                {
  1788.                   png_memcpy(dp, v, pixel_bytes);
  1789.                   dp -= pixel_bytes;
  1790.                }
  1791.                sp -= pixel_bytes;
  1792.             }
  1793.             break;
  1794.          }
  1795.       }
  1796.       row_info->width = final_width;
  1797.       row_info->rowbytes = ((final_width *
  1798.          (png_uint_32)row_info->pixel_depth + 7) >> 3);
  1799.    }
  1800. }
  1801. #endif
  1802.  
  1803. void
  1804. png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
  1805.    png_bytep prev_row, int filter)
  1806. {
  1807.    png_debug(1, "in png_read_filter_row\n");
  1808.    png_debug2(2,"row = %d, filter = %d\n", png_ptr->row_number, filter);
  1809.  
  1810.    switch (filter)
  1811.    {
  1812.       case PNG_FILTER_VALUE_NONE:
  1813.          break;
  1814.       case PNG_FILTER_VALUE_SUB:
  1815.       {
  1816.          png_uint_32 i;
  1817.          int bpp;
  1818.          png_bytep rp;
  1819.          png_bytep lp;
  1820.  
  1821.          bpp = (row_info->pixel_depth + 7) / 8;
  1822.          for (i = (png_uint_32)bpp, rp = row + bpp, lp = row;
  1823.             i < row_info->rowbytes; i++, rp++, lp++)
  1824.          {
  1825.             *rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff);
  1826.          }
  1827.          break;
  1828.       }
  1829.       case PNG_FILTER_VALUE_UP:
  1830.       {
  1831.          png_uint_32 i;
  1832.          png_bytep rp;
  1833.          png_bytep pp;
  1834.  
  1835.          for (i = 0, rp = row, pp = prev_row;
  1836.             i < row_info->rowbytes; i++, rp++, pp++)
  1837.          {
  1838.             *rp = (png_byte)(((int)(*rp) + (int)(*pp)) & 0xff);
  1839.          }
  1840.          break;
  1841.       }
  1842.       case PNG_FILTER_VALUE_AVG:
  1843.       {
  1844.          png_uint_32 i;
  1845.          int bpp;
  1846.          png_bytep rp;
  1847.          png_bytep pp;
  1848.          png_bytep lp;
  1849.  
  1850.          bpp = (row_info->pixel_depth + 7) / 8;
  1851.          for (i = 0, rp = row, pp = prev_row;
  1852.             i < (png_uint_32)bpp; i++, rp++, pp++)
  1853.          {
  1854.             *rp = (png_byte)(((int)(*rp) +
  1855.                ((int)(*pp) / 2)) & 0xff);
  1856.          }
  1857.          for (lp = row; i < row_info->rowbytes; i++, rp++, lp++, pp++)
  1858.          {
  1859.             *rp = (png_byte)(((int)(*rp) +
  1860.                (int)(*pp + *lp) / 2) & 0xff);
  1861.          }
  1862.          break;
  1863.       }
  1864.       case PNG_FILTER_VALUE_PAETH:
  1865.       {
  1866.          int bpp;
  1867.          png_uint_32 i;
  1868.          png_bytep rp;
  1869.          png_bytep pp;
  1870.          png_bytep lp;
  1871.          png_bytep cp;
  1872.  
  1873.          bpp = (row_info->pixel_depth + 7) / 8;
  1874.          for (i = 0, rp = row, pp = prev_row,
  1875.             lp = row - bpp, cp = prev_row - bpp;
  1876.             i < row_info->rowbytes; i++, rp++, pp++, lp++, cp++)
  1877.          {
  1878.             int a, b, c, pa, pb, pc, p;
  1879.  
  1880.             b = *pp;
  1881.             if (i >= (png_uint_32)bpp)
  1882.             {
  1883.                c = *cp;
  1884.                a = *lp;
  1885.             }
  1886.             else
  1887.             {
  1888.                a = c = 0;
  1889.             }
  1890.             p = a + b - c;
  1891.             pa = abs(p - a);
  1892.             pb = abs(p - b);
  1893.             pc = abs(p - c);
  1894.  
  1895.             if (pa <= pb && pa <= pc)
  1896.                p = a;
  1897.             else if (pb <= pc)
  1898.                p = b;
  1899.             else
  1900.                p = c;
  1901.  
  1902.             *rp = (png_byte)(((int)(*rp) + p) & 0xff);
  1903.          }
  1904.          break;
  1905.       }
  1906.       default:
  1907.          png_error(png_ptr, "Bad adaptive filter type");
  1908.          break;
  1909.    }
  1910. }
  1911.  
  1912. void
  1913. png_read_finish_row(png_structp png_ptr)
  1914. {
  1915.    png_debug(1, "in png_read_finish_row\n");
  1916.    png_ptr->row_number++;
  1917.    if (png_ptr->row_number < png_ptr->num_rows)
  1918.       return;
  1919.  
  1920.    if (png_ptr->interlaced)
  1921.    {
  1922.       png_ptr->row_number = 0;
  1923.       png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
  1924.       do
  1925.       {
  1926.          png_ptr->pass++;
  1927.          if (png_ptr->pass >= 7)
  1928.             break;
  1929.          png_ptr->iwidth = (png_ptr->width +
  1930.             png_pass_inc[png_ptr->pass] - 1 -
  1931.             png_pass_start[png_ptr->pass]) /
  1932.             png_pass_inc[png_ptr->pass];
  1933.          png_ptr->irowbytes = ((png_ptr->iwidth *
  1934.             png_ptr->pixel_depth + 7) >> 3) + 1;
  1935.          if (!(png_ptr->transformations & PNG_INTERLACE))
  1936.          {
  1937.             png_ptr->num_rows = (png_ptr->height +
  1938.                png_pass_yinc[png_ptr->pass] - 1 -
  1939.                png_pass_ystart[png_ptr->pass]) /
  1940.                png_pass_yinc[png_ptr->pass];
  1941.             if (!(png_ptr->num_rows))
  1942.                continue;
  1943.          }
  1944.          if (png_ptr->transformations & PNG_INTERLACE)
  1945.             break;
  1946.       } while (png_ptr->iwidth == 0);
  1947.  
  1948.       if (png_ptr->pass < 7)
  1949.          return;
  1950.    }
  1951.  
  1952.    if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
  1953.    {
  1954.       char extra;
  1955.       int ret;
  1956.  
  1957.       png_ptr->zstream.next_out = (Byte *)&extra;
  1958.       png_ptr->zstream.avail_out = (uInt)1;
  1959.       do
  1960.       {
  1961.          if (!(png_ptr->zstream.avail_in))
  1962.          {
  1963.             while (!png_ptr->idat_size)
  1964.             {
  1965.                png_byte chunk_length[4];
  1966.  
  1967.                png_crc_finish(png_ptr, 0);
  1968.  
  1969.                png_read_data(png_ptr, chunk_length, 4);
  1970.                png_ptr->idat_size = png_get_uint_32(chunk_length);
  1971.  
  1972.                png_reset_crc(png_ptr);
  1973.                png_crc_read(png_ptr, png_ptr->chunk_name, 4);
  1974.                if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
  1975.                   png_error(png_ptr, "Not enough image data");
  1976.  
  1977.             }
  1978.             png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
  1979.             png_ptr->zstream.next_in = png_ptr->zbuf;
  1980.             if (png_ptr->zbuf_size > png_ptr->idat_size)
  1981.                png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
  1982.             png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
  1983.             png_ptr->idat_size -= png_ptr->zstream.avail_in;
  1984.          }
  1985.          ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
  1986.          if (ret == Z_STREAM_END)
  1987.          {
  1988.             if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
  1989.                png_ptr->idat_size)
  1990.                png_error(png_ptr, "Extra compressed data");
  1991.             png_ptr->mode |= PNG_AFTER_IDAT;
  1992.             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
  1993.             break;
  1994.          }
  1995.          if (ret != Z_OK)
  1996.             png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
  1997.                       "Decompression Error");
  1998.  
  1999.          if (!(png_ptr->zstream.avail_out))
  2000.             png_error(png_ptr, "Extra compressed data");
  2001.  
  2002.       } while (1);
  2003.       png_ptr->zstream.avail_out = 0;
  2004.    }
  2005.  
  2006.    if (png_ptr->idat_size || png_ptr->zstream.avail_in)
  2007.       png_error(png_ptr, "Extra compression data");
  2008.  
  2009.    inflateReset(&png_ptr->zstream);
  2010.  
  2011.    png_ptr->mode |= PNG_AFTER_IDAT;
  2012. }
  2013.  
  2014. void
  2015. png_read_start_row(png_structp png_ptr)
  2016. {
  2017.    int max_pixel_depth;
  2018.    png_uint_32 rowbytes;
  2019.  
  2020.    png_debug(1, "in png_read_start_row\n");
  2021.    png_ptr->zstream.avail_in = 0;
  2022.    png_init_read_transformations(png_ptr);
  2023.    if (png_ptr->interlaced)
  2024.    {
  2025.       if (!(png_ptr->transformations & PNG_INTERLACE))
  2026.          png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
  2027.             png_pass_ystart[0]) / png_pass_yinc[0];
  2028.       else
  2029.          png_ptr->num_rows = png_ptr->height;
  2030.  
  2031.       png_ptr->iwidth = (png_ptr->width +
  2032.          png_pass_inc[png_ptr->pass] - 1 -
  2033.          png_pass_start[png_ptr->pass]) /
  2034.          png_pass_inc[png_ptr->pass];
  2035.       png_ptr->irowbytes = ((png_ptr->iwidth *
  2036.          png_ptr->pixel_depth + 7) >> 3) + 1;
  2037.    }
  2038.    else
  2039.    {
  2040.       png_ptr->num_rows = png_ptr->height;
  2041.       png_ptr->iwidth = png_ptr->width;
  2042.       png_ptr->irowbytes = png_ptr->rowbytes + 1;
  2043.    }
  2044.    max_pixel_depth = png_ptr->pixel_depth;
  2045.  
  2046. #if defined(PNG_READ_PACK_SUPPORTED)
  2047.    if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
  2048.       max_pixel_depth = 8;
  2049. #endif
  2050.  
  2051. #if defined(PNG_READ_EXPAND_SUPPORTED)
  2052.    if (png_ptr->transformations & PNG_EXPAND)
  2053.    {
  2054.       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
  2055.       {
  2056.          if (png_ptr->num_trans)
  2057.             max_pixel_depth = 32;
  2058.          else
  2059.             max_pixel_depth = 24;
  2060.       }
  2061.       else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
  2062.       {
  2063.          if (max_pixel_depth < 8)
  2064.             max_pixel_depth = 8;
  2065.          if (png_ptr->num_trans)
  2066.             max_pixel_depth *= 2;
  2067.       }
  2068.       else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
  2069.       {
  2070.          if (png_ptr->num_trans)
  2071.          {
  2072.             max_pixel_depth *= 4;
  2073.             max_pixel_depth /= 3;
  2074.          }
  2075.       }
  2076.    }
  2077. #endif
  2078.  
  2079. #if defined(PNG_READ_FILLER_SUPPORTED)
  2080.    if (png_ptr->transformations & (PNG_FILLER))
  2081.    {
  2082.       if (max_pixel_depth < 32)
  2083.          max_pixel_depth = 32;
  2084.    }
  2085. #endif
  2086.  
  2087. #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
  2088.    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
  2089.    {
  2090.       if ((png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
  2091.          png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  2092.       {
  2093.          if (max_pixel_depth <= 16)
  2094.             max_pixel_depth = 32;
  2095.          else if (max_pixel_depth <= 32)
  2096.             max_pixel_depth = 64;
  2097.       }
  2098.       else
  2099.       {
  2100.          if (max_pixel_depth <= 8)
  2101.             max_pixel_depth = 24;
  2102.          else if (max_pixel_depth <= 16)
  2103.             max_pixel_depth = 48;
  2104.       }
  2105.    }
  2106. #endif
  2107.  
  2108.    /* align the width on the next larger 8 pixels.  Mainly used
  2109.       for interlacing */
  2110.    rowbytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
  2111.    /* calculate the maximum bytes needed, adding a byte and a pixel
  2112.       for safety sake */
  2113.    rowbytes = ((rowbytes * (png_uint_32)max_pixel_depth + 7) >> 3) +
  2114.       1 + ((max_pixel_depth + 7) >> 3);
  2115. #ifdef PNG_MAX_MALLOC_64K
  2116.    if (rowbytes > 65536L)
  2117.       png_error(png_ptr, "This image requires a row greater than 64KB");
  2118. #endif
  2119.    png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, rowbytes);
  2120.  
  2121. #ifdef PNG_MAX_MALLOC_64K
  2122.    if (png_ptr->rowbytes + 1 > 65536L)
  2123.       png_error(png_ptr, "This image requires a row greater than 64KB");
  2124. #endif
  2125.    png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1);
  2126.  
  2127.    png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
  2128.  
  2129.    png_debug1(3, "width = %d,\n", png_ptr->width);
  2130.    png_debug1(3, "height = %d,\n", png_ptr->height);
  2131.    png_debug1(3, "iwidth = %d,\n", png_ptr->iwidth);
  2132.    png_debug1(3, "num_rows = %d\n", png_ptr->num_rows);
  2133.    png_debug1(3, "rowbytes = %d,\n", png_ptr->rowbytes);
  2134.    png_debug1(3, "irowbytes = %d,\n", png_ptr->irowbytes);
  2135.  
  2136.    png_ptr->flags |= PNG_FLAG_ROW_INIT;
  2137. }
  2138.